package com.sense.kukoo.common.anim

import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.View
import com.sense.kukoo.common.utils.ApplicationContext
import com.sense.kukoo.lib_logger.LoggerManager
import kotlin.math.absoluteValue

class BottomMotionAnimHelper {

    private val TAG: String = javaClass.simpleName
    private val toDismissPercent: Float = 0.3F
    private var defAnimateDuration = 400L
    private val isLogTouchEvent = false //用于调试

    private var firstTranslationY: Float = 0F
    private var contentHeight: Float = 0F
    private var touchY: Float = Float.MIN_VALUE
    private var translationY: Float = 0F

    private lateinit var bgView: View
    private lateinit var contentView: View

    private var endAction: ()->Unit = {}

    fun init(bgView:View, contentView: View, first: Float, action : ()->Unit){
        setView(bgView, contentView)
        setFirstTranslationY(first)
        setEndAction(action)
    }

    fun setView(bgView:View, contentView:View){
        this.bgView = bgView
        this.contentView = contentView
        //
        bgView.setOnClickListener {
            animateToFinish()
        }
    }

    fun setFirstTranslationY(first: Float){
        firstTranslationY = first
    }

    fun setAnimateDuration(duration: Long){
        defAnimateDuration = duration
    }

    fun setEndAction(action : ()->Unit){
        endAction = action
    }

    fun animateToStart(){
        contentView.setTranslationY(firstTranslationY)
        contentView.animate()
            .translationY(0F)
            .setDuration(defAnimateDuration)
            .withEndAction {
                initContent()
                initTouchEvent()
            }
            .start()
    }

    fun animateToFinish(){
        val duration = calculateAnimateDuration(contentHeight - contentView.translationY)
        contentView.animate()
            .translationY(contentHeight)
            .setDuration(duration)
            .withEndAction {
                endAction()
            }
            .start()
    }

    private fun initContent(){
        contentHeight = contentView.height.toFloat()
    }

    private fun calculateAnimateDuration(moveY: Float): Long {
        var duration = (defAnimateDuration * (moveY / contentHeight)).toLong().absoluteValue
        duration = if (duration > defAnimateDuration) defAnimateDuration else duration
        duration = if(duration < 0 ) 16L else duration
        return duration
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initTouchEvent(){
        contentView.setOnTouchListener { v, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
                    onTouchStart(event.y)
                }
                MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
                    onTouchFinish(event.y)
                }
            }
            return@setOnTouchListener true
        }
    }

    private fun onTouchStart(y: Float) {
        if (touchY == Float.MIN_VALUE) {
            touchY = y
        }
        val moveY: Float = y - touchY
        translationY += moveY
        if (translationY > 0) {
            contentView.translationY = translationY
        }
        if (isLogTouchEvent) {
            LoggerManager.d(
                    TAG,
                    "onTouchStart -> y=${y}, touchY=${touchY}, moveY=${moveY}, translationY=${translationY}"
            )
        }
    }

    private fun onTouchFinish(y: Float) {
        if (isLogTouchEvent) {
            LoggerManager.d(TAG, "onTouchFinish -> translationY=${translationY}, height=${contentView.height}")
        }
        val toDismiss: Boolean = translationY > contentView.height * toDismissPercent
        if (toDismiss) {
            animateToFinish()
        } else {
            val duration = calculateAnimateDuration(contentView.translationY)
            contentView.animate().translationY(0F).setDuration(duration).start()
        }
        touchY = Float.MIN_VALUE
        translationY = 0F
    }
}